package main

import (
	"net"
	"strings"
)

type User struct {
	Name   string
	Addr   string
	C      chan string
	conn   net.Conn
	Server *Server
}

func NewUserObj(conn net.Conn, server *Server) *User {
	user := &User{
		Name:   conn.RemoteAddr().String(),
		Addr:   conn.RemoteAddr().String(),
		C:      make(chan string),
		conn:   conn,
		Server: server,
	}

	// 启动监听当前user channel消息的goroutine
	go user.ListeningMessage()

	return user
}

// 监听当前User channel的方法，一旦有消息，就直接发送给对端客户端
func (this *User) ListeningMessage() {
	for {
		msg := <-this.C
		this.conn.Write([]byte(msg + "\n"))
	}
}

// 用户上线
func (this *User) OnLine() {
	// 用户上线，将用户加入到onlineMap中
	this.Server.MapLock.Lock()
	this.Server.OnLineMap[this.Name] = this
	this.Server.MapLock.Unlock()
	this.Server.BroadCast(this, "已上线")
}

// 用户下线
func (this *User) OffLine() {
	this.Server.MapLock.Lock()
	delete(this.Server.OnLineMap, this.Name)
	this.Server.MapLock.Unlock()
	this.Server.BroadCast(this, "下线")
}

// 处理用户消息
func (this *User) HandlerMessage(msg string) {
	// 查询当前在线的其他用户
	if msg == "who" {
		this.Server.MapLock.Lock()
		for _, user := range this.Server.OnLineMap {
			if user.Addr != this.Addr {
				onLineMap := "[" + user.Addr + "]" + user.Name + "：在线...\n"
				this.SendMsg(onLineMap)
			}
		}
		this.Server.MapLock.Unlock()
		return
	}
	// 更新用户名
	if strings.Index(msg, "rename|") == 0 {
		newName := strings.Split(msg, "|")[1]

		if _, exist := this.Server.OnLineMap[newName]; exist {
			this.SendMsg("当前用户名已经被使用\n")
			return
		}

		this.Server.MapLock.Lock()
		this.Server.OnLineMap[newName] = this
		delete(this.Server.OnLineMap, this.Name)
		this.Server.MapLock.Unlock()
		this.Name = newName
		this.SendMsg("您已经更新用户名：" + this.Name + "\n")
		return
	}

	// 私聊其他人
	if strings.Index(msg, "to|") == 0 {
		msgList := strings.Split(msg, "|")
		userName := msgList[1]
		message := ""
		if len(msgList) == 3 {
			message = msgList[2]
		} else {
			this.SendMsg("消息内容为空，请重新发送\n")
			return
		}
		user, exist := this.Server.OnLineMap[userName]
		if exist {
			user.SendMsg(this.Name + "对您说：" + message + "\n")
		} else {
			this.SendMsg("当前用户不存在或已下线\n")
		}
		return
	}

	this.Server.BroadCast(this, msg)
}

// 给当前用户发消息
func (this *User) SendMsg(msg string) {
	this.conn.Write([]byte(msg))
}
